<template>
  <div class="app-container">
    <div class="filter-container">
      <div class="stat-view--container">
        <el-form :inline="true" class="form-inline">
          <el-form-item label="平台名称">
            <el-select v-model="statCondition.platformName" placeholder="平台名称" style="width: 300px" class="filter-item" >
              <el-option v-for="item in platformOptions" :key="item.name" :label="item.name===''?'全部':item.describe+'('+item.name+')'" :value="item.name===''?'':item.name"/>
            </el-select>
          </el-form-item>
          <el-form-item label="日期范围">
            <el-date-picker
              v-model="dateRange"
              :picker-options="pickerOptions"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              class="filter-item"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 400px"
            />
          </el-form-item>
          <el-form-item label="时间间隔">
            <el-select v-model="statCondition.interval" placeholder="时间间隔" style="width: 150px" class="filter-item" >
              <el-option v-for="item in intervalOptions" :key="item.name" :label="item.name===''?'全部':item.describe+'('+item.name+')'" :value="item.name===''?'':item.name"/>
            </el-select>
          </el-form-item>

          <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleStat">统计</el-button>
          <el-button v-waves v-if="isStatOver" class="filter-item" type="primary" icon="el-icon-tickets" @click="handleStatDetail">明细</el-button>
        </el-form>
        <div id="myChart" ref="chart" :style="{width: '100%', height: '750px'}"/>
      </div>

      <el-dialog :title="statDetailTitle" :visible.sync="statDetailVisible" top="2vh" width="90%" >
        <el-button v-waves v-if="isStatOver" class="filter-item" type="primary" icon="el-icon-download" style="float: right" @click="handleDownload">导出</el-button>
        <el-table :data="statDetailData" :border="true" >
          <el-table-column property="platformName" label="平台名" width="" sortable header-align="center"/>
          <el-table-column v-for="date in statAllDate" :property="date" :label="date.replace(' 00:00:00','')" header-align="center">
            <el-table-column :property="date+'-okCount'" label="成功" width="" sortable header-align="center"/>
            <el-table-column :property="date+'-errorCount'" label="失败" width="" sortable header-align="center"/>
            <el-table-column :property="date+'-errorRate'" label="错误率%" width="" sortable header-align="center"/>
            <el-table-column :property="date+'-percent99'" label="99th" width="" sortable header-align="center"/>
            <el-table-column :property="date+'-percent995'" label="99.5th" width="" sortable header-align="center"/>
          </el-table-column>
        </el-table>
        <span slot="footer" class="dialog-footer">
          <el-button v-waves v-if="isStatOver" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">导出</el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import waves from '@/directive/waves'
import { stat } from '@/api/stat'
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
export default {
  name: 'StatUnion',
  directives: { waves },
  components: { },
  data() {
    return {
      statType: 'statUnion',
      statCondition: {
        platformName: this.$store.getters.platforms[0].name,
        interval: 'Auto',
        fromDate: '',
        toDate: ''
      },
      listLoading: false,
      dateRange: undefined,
      platformOptions: this.$store.getters.platforms,
      intervalOptions: [
        { 'name': 'Auto', describe: '自动' },
        { 'name': 'Hour', describe: '小时' },
        { 'name': 'Day', describe: '天' },
        { 'name': 'Week', describe: '星期' },
        { 'name': 'Month', describe: '月' }
      ],
      pickerOptions: {
        shortcuts: [{
          text: '最近1天',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 1)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近3天',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 3)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近7天',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }]
      },
      platformDateMap: new Map(),
      statDetailTitle: '',
      statDetailVisible: false,
      isStatOver: false,
      statDetailData: [],
      statAllDate: [],
      statAllPlatform: [],
      downloadLoading: false
    }
  },
  created() {
  },
  mounted() {
    // 删除全部
    /*
    if (this.platformOptions.length>0 && this.platformOptions[this.platformOptions.length - 1].name === "") {
      this.platformOptions.splice(this.platformOptions.length-1 ,1);
    }
    */
  },
  methods: {
    initChart(myChart, resultData) {
      const xAxisData = []
      const okCountData = []
      const errorCountData = []
      const percent99Data = []
      const percent995Data = []
      this.statAllDate = []
      this.statAllPlatform = []

      for (let i = 0; i < resultData.length; i++) {
        const currDate = resultData[i].statDate
        const currPlatform = resultData[i].platformName

        if (!xAxisData.includes(currDate)) {
          xAxisData.push(currDate)
          this.statAllDate.push(currDate)
        }

        if (!this.statAllPlatform.includes(currPlatform)) {
          this.statAllPlatform.push(currPlatform)
        }

        this.platformDateMap.set(currPlatform + '_' + currDate, resultData[i])
      }

      // 每日将多个平台的求和汇总
      for (const currDate of xAxisData) {
        let okCount = 0, errorCount = 0, percent99 = 0, percent995 = 0
        let count = 0
        for (const platformName of this.statAllPlatform) {
          const key = platformName + '_' + currDate
          if (this.platformDateMap.has(key)) {
            const statData = this.platformDateMap.get(key)
            okCount += statData.okCount
            errorCount += statData.errorCount
            percent99 += statData.percent99
            percent995 += statData.percent995
            count++
          }
        }

        okCountData.push(
          {
            value: okCount,
            itemStyle: { 'color': '#24b985' }
          }
        )
        errorCountData.push(
          {
            value: errorCount,
            itemStyle: { 'color': '#c93436' }
          }
        )

        percent99Data.push(Math.round(percent99 / count))
        percent995Data.push(Math.round(percent995 / count))
      }

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
            crossStyle: {
              color: '#999'
            }
          },
          formatter: function(obj) {
            let html = obj[0].axisValue + '<br>'
            let sumCount = obj[0].value + obj[1].value
            let sumUnit = '次'
            if (sumCount > 10000) {
              sumCount = (sumCount / 10000).toFixed(3)
              sumUnit = '万次'
            }
            html += '总计调用:' + sumCount + sumUnit + '<br>'

            let okCount = obj[0].value
            let okUnit = '次'
            if (okCount > 10000) {
              okCount = (okCount / 10000).toFixed(3)
              okUnit = '万次'
            }
            let errCount = obj[1].value
            let errUnit = '次'
            if (errCount > 10000) {
              errCount = (errCount / 10000).toFixed(3)
              errUnit = '万次'
            }
            html += obj[0].marker + obj[0].seriesName + ':' + okCount + okUnit + '<br>'
            html += obj[1].marker + obj[1].seriesName + ':' + errCount + errUnit + '<br>'
            html += obj[2].marker + obj[2].seriesName + ':' + obj[2].value + 'ms' + '<br>'
            html += obj[3].marker + obj[3].seriesName + ':' + obj[3].value + 'ms'

            return html
          }
        },
        toolbox: {
          feature: {
            dataView: { show: true, readOnly: false },
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        legend: {
          data: ['正常数', '错误数', '99%耗时', '99.5%耗时']
        },
        xAxis: [
          {
            type: 'category',
            data: xAxisData,
            axisPointer: {
              type: 'shadow'
            }
          }
        ],
        yAxis: [
          {
            type: 'value',
            name: '调用次数',
            axisLabel: {
              formatter: '{value} 次'
            }
          },
          {
            type: 'value',
            name: '百分位耗时',
            axisLabel: {
              formatter: '{value} ms'
            }
          }
        ],
        series: [
          {
            name: '正常次数',
            type: 'bar',
            stack: '调用',
            data: okCountData
          },
          {
            name: '异常次数',
            type: 'bar',
            stack: '调用',
            data: errorCountData
          },
          {
            name: '99%耗时',
            type: 'line',
            yAxisIndex: 1,
            data: percent99Data
          },
          {
            name: '99.5%耗时',
            type: 'line',
            yAxisIndex: 1,
            data: percent995Data
          }
        ]
      }
      myChart.clear()
      myChart.setOption(option)
    },
    handleStat() {
      this.listLoading = true
      this.statCondition.fromDate = (this.dateRange === undefined || this.dateRange === null) ? '' : this.dateRange[0]
      this.statCondition.toDate = (this.dateRange === undefined || this.dateRange === null) ? '' : this.dateRange[1]
      const myChart = echarts.init(this.$refs.chart)
      stat(this.statType, this.statCondition).then(response => {
        if (response.code === '0000') {
          this.initChart(myChart, response.data)
        }
        this.listLoading = false
        this.isStatOver = true
      })
    },
    handleStatDetail() {
      this.statDetailTitle = '统计明细'
      this.statDetailData = []
      for (const platformName of this.statAllPlatform) {
        if (platformName.length > 0) {
          let tempPlatform = { 'platformName': platformName }
          for (const item of this.platformOptions) {
            if (item.name === platformName) {
              tempPlatform = { 'platformName': item.describe }
              break
            }
          }
          for (const date of this.statAllDate) {
            const key = platformName + '_' + date
            if (this.platformDateMap.has(key)) {
              const statData = this.platformDateMap.get(key)
              tempPlatform[date + '-okCount'] = statData.okCount
              tempPlatform[date + '-errorCount'] = statData.errorCount
              tempPlatform[date + '-percent99'] = statData.percent99
              tempPlatform[date + '-percent995'] = statData.percent995
            } else {
              tempPlatform[date + '-okCount'] = 0
              tempPlatform[date + '-errorCount'] = 0
              tempPlatform[date + '-percent99'] = 0
              tempPlatform[date + '-percent995'] = 0
            }
            const total = tempPlatform[date + '-okCount'] + tempPlatform[date + '-errorCount']
            if (total > 0) {
              tempPlatform[date + '-errorRate'] = (tempPlatform[date + '-errorCount'] / total * 100).toFixed(4)
            } else {
              tempPlatform[date + '-errorRate'] = 0
            }
          }

          this.statDetailData.push(tempPlatform)
        }
      }

      this.statDetailVisible = true
    },
    handleDownload() {
      this.downloadLoading = true
      import('@/vendor/Export2Excel').then(excel => {
        const tHeader = ['平台名']
        const filterVal = ['platformName']
        const secondHeader = [{ 'platformName': '' }]

        for (const date of this.statAllDate) {
          tHeader.push(date.replace(' 00:00:00', ''))
          tHeader.push(' ')
          tHeader.push(' ')
          tHeader.push(' ')
          tHeader.push(' ')
          secondHeader[0][date + '-okCount'] = '成功'
          secondHeader[0][date + '-errorCount'] = '失败'
          secondHeader[0][date + '-errorRate'] = '错误率%'
          secondHeader[0][date + '-percent99'] = '99th(ms)'
          secondHeader[0][date + '-percent995'] = '99.5th(ms)'
          filterVal.push(date + '-okCount')
          filterVal.push(date + '-errorCount')
          filterVal.push(date + '-errorRate')
          filterVal.push(date + '-percent99')
          filterVal.push(date + '-percent995')
        }
        const jsonData = secondHeader.concat(this.statDetailData)
        const data = this.formatJson(filterVal, jsonData)
        excel.export_json_to_excel({
          header: tHeader,
          data,
          filename: 'table-list'
        })
        this.downloadLoading = false
      })
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map(v => filterVal.map(j => {
        if (j === 'timestamp') {
          return parseTime(v[j])
        } else {
          return v[j]
        }
      }))
    }
  }
}
</script>
<style>
</style>

